package foundation.图论.最小生成树;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

/**
 * {@code Kruskal} 算法（最常用）
 * <p>
 * 用于生成最小生成树的算法，步骤如下
 * <ol>
 *   <li>把所有的边，根据权值从小到大排序，从权值小的边开始考虑</li>
 *   <li>如果连接当前的边不会形成环，就选择当前的边</li>
 *   <li>如果连接当前的边会形成环，就不要当前的边</li>
 *   <li>考察完所有边之后，最小生成树也就得到了</li>
 * </ol>
 */
public class Kruskal {
    static int N = 5001;
    static int M = 200001;

    static int cur;
    static int[] fa = new int[N];
    static int[][] arr = new int[M][3];
    static int select;
    static int n, m;
    static int res = 0;


    public static int find(int i) {
        if (i != fa[i]) {
            fa[i] = find(fa[i]);
        }
        return fa[i];
    }

    public static boolean union(int x, int y) {
        int fx = find(x);
        int fy = find(y);
        if (fx != fy) {
            fa[fx] = fy;
            return true;
        } else {
            return false;
        }
    }



    public static void inputAndInit() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i < m; i++) {
            arr[i][0] = sc.nextInt();
            arr[i][1] = sc.nextInt();
            arr[i][2] = sc.nextInt();
        }
        for (int i = 0; i < n; i++) {
            fa[i] = i;
        }
        res = 0;
    }


    public static boolean kruskal() {
        // 按权值从小到大排序
        Arrays.sort(arr, 0, m, Comparator.comparingInt(o -> o[2]));
        for (int i = 0; i < m; i++) {
            if (union(arr[i][0], arr[i][1])) {
                res += arr[i][2];
                select++;
            }
        }
        // select 为选的边
        return select == n - 1;
    }

    public static void main(String[] args) {
        inputAndInit();
        if (kruskal()) {
            System.out.println(res);
        } else {
            System.out.println("orz");
        }
    }


}
